Serverless 的喧哗与骚动
戳蓝字“CSDN云计算”关注我们哦!
导读:从 2016 年 AWS 发布 Lambda 以来,全世界的开发者和云厂商对 Serverless 的热情在不断高涨。假设不想在开发应用程序并将其部署在服务器上的过程细节上花费精力,是否有一种简单的架构模型能够满足我们这种想法呢?答案已经存在,这就是今天软件架构世界中新鲜但是很热门的一个话题——Serverless(无服务器)架构。本文作者将利用自身多年的研发经验,带领我们深入了解 Serverless 行业的发展!
Serverless is like teenage sex
Big data is like teenage sex: Everyone talks about it, nobody really knows how to do it, everyone thinks everyone else is doing it, so everyone claims they are doing it.
我们把Big data换一下:AI is like teenage sex: Everyone talks about it, nobody really knows how to do it, everyone thinks everyone else is doing it, so everyone claims they are doing it.
我们把AI换成Serverless:Serverless is like teenage sex: Everyone talks about it, nobody really knows how to do it, everyone thinks everyone else is doing it, so everyone claims they are doing it.
所有人都在说 Serverless;
几乎没人知道怎么落地 Serverless;
但是大家都觉得其他人在大力做 Serverless;
所以大家都宣称自己在做 Serverless。
它是开放(开源)的。因此不会有 vendor lock-in,所有人可以放心用;
有大量的成功案例。很多人将其用到关键的商业系统中,因此得到了广泛验证。
今天 Serverless/FaaS 领域有这个东西吗?还没有。
Serverless 的愿景
下面是来自 Google Trends 的一个图,其中红色是 Microservices,蓝色是 Serverless。
从 2016 年 AWS 发布 Lambda 以来,全世界的开发者和云厂商对 Serverless 的热情在不断高涨,这说明大家对 Serverless 所描绘的愿景都非常 buy in。这个愿景是什么呢?
图片来源网络
愿景是无服务器?但工程师们都知道服务器本质上是存在的,最多是加一层抽象,让我们看不到服务器,但它依旧很好的发挥作用。
我个人觉得有关 Serverless 愿景,描绘最清楚的是一个比喻,这个比喻来自 UC Berkeley 在今年2月发表的那篇论文[1]:
图片来源网络
图片来源网络
是不是对图中的这些寄存器、栈、程序计数器、以及相关的汇编指令感到很陌生了?如果让你用这样的语言写业务逻辑,那效率必然会变得非常低。
幸好我们有 Java,Go,JavaScript 这样的高级语言,而这些高级语言还配套了相关的编译器/虚拟机,编译器/虚拟机能够高效地把面向业务的高级语言翻译成面向机器的汇编/机器码。
今天,虽然基本的计算机体系结构没有发生本质的变化,但我们的程序所运行的环境,相比较20年前,已经发生了本质的变化。20 年前的程序大都跑在单机上,今天我们的程序都要为了跑在云上而设计了。
为了让程序跑在云上,我们就需要配套的工作,包括云资源(容器、缓存、队列)的申请和回收、包括弹性伸缩的控制,等等。这些事情和业务逻辑没有任何关系,但研发/运维同学却为此花费了大量的时间。
我想做一个不太成熟的类比:
单机时代,操作系统管理了硬件资源,贴着资源层,高级语言让程序员描述业务,贴着业务层,编译器/VM 把高级语言翻译成机器码,交给操作系统; 今天的云时代,资源的单位不再是 CPU、内存、硬盘了,而是容器、分布式队列、分布式缓存、分布式文件系统。
图片来源网络
今天我们把应用程序往云上搬的时候(a.k.a Cloud Native),往往都会做两件事情:
第一是把巨型应用拆小,微服务化; 第二就是摇身一变成为 yaml 工程师,写很多 yaml 文件来管理云上的资源。
1. 编程语言和框架
目前主流的编程语言基本都是假设单机体系架构运行的,面对分布式问题的时候,再叠一层框架上去。其对应的资源也依旧停留在单机体系结构的那些资源上(当然这里是有例外的,比如 erlang/OTP 天生就是为分布式设计的)。
云时代,首先基本的资源单位发生了变化,从原来的 cpu、内存变成了容器、函数、分布式队列等等;其次,云天生分布式,因此单机时代大行其道的同步模型就不再适合。
2. 编译器
程序员不应该花大量时间去写 yaml 文件,这些面向资源的 yaml 文件应该是由机器生成的,我称之为云编译器,高级编程语言用来表达业务的领域模型和逻辑,云编译器负责将语言编译成资源描述。
我个人很看好 Erlang 的 Actor 模型,这个模型在其他语言上也有实现,例如语法参考 Ruby 并运行在 Erlang OTP 上的 Elixir,JVM 上的 Akka,以及 .NET 上的 Orleans。
不同于其他语言的设计,Actor 模型从一开始就是基于分布式的前提做的设计,因此这种模型如果把其对应的资源管理换成纯粹的云资源管理,我觉得是有极大可行性的。
如果用一句话来总结,我觉得 Serverless 的愿景应该是:
Write locally, compile to the cloud.
大家在忙什么
为了能够稍微清晰一点地去看这一大堆的产品和技术,我简单的把 Serverless 领域做的事情分了三个层,自下而上分别是资源层、DevOps 层和框架及运行时层。
图片来源网络
第一是其模型非常完备; 第二是其生态发展非常迅速和健康。很有可能未来所有云厂商都要去兼容 Knative 的标准,就像今天所有云厂商都在兼容 Kubernetes 一样。
以下是 Knative 近一年的贡献者及贡献数量的增长情况,数据来自演讲「Knative a Year Later: Serverless, Kubernetes and You」。[2]
图片来源网络
框架和运行时层呢,由于个人经验所限,我看的仅仅是 Java 领域,其实核心的还是在解决 Java 应用程序启动慢的问题(GraalVM)。当然框架如何避免 vendor lock-in 也很重要,谁都怕被一家云厂商绑定,怕换个云厂商要改代码,这方面主要是 Spring Cloud Function 在做。
刚需在哪里
图片来源网络
很多技术产品基本都是经历了如下四个阶段:
初创期:一个小团队围绕新的业务做试错,从无到有,技术上什么能快速上线用什么;
成熟期:业务成功了,用户在不断增多,业务也变得越来越复杂;
平台期:业务太成功了,就希望把已经沉淀的能力赋能给其他类似的业务;
云产品期:平台太成功了,就希望做成云服务,赋能社会上类似的业务,发挥更大的价值。
框架和运行时的创新
前面所说的刚需都是集中在稳定性、安全性及资源成本的角度来讨论的。除此之外我们还需要讨论另外一个话题,那就是开发效率,而开发效率具体到技术是体现在框架上的。
我们可以进一步的把框架分成两类:
面向技术问题提升开发效率的框架:如 Spring 通过依赖注入解决对象组装问题;HSF 解决分布式同步通讯问题;RocketMQ 解决分布式异步通讯问题;Hystrix 解决分布式通讯引入的网络不可靠问题等等。 通过使用这些框架,技术的天然复杂度在很大程度被屏蔽掉了。 面向业务问题提升开发效率的框架:阿里的很多业务平台团队都会根据自己的场景(如交易、店铺、供应链)开发业务型框架,赋能开发快速迭代业务。
通常,面向技术问题的框架会有一个团队研发,而面向业务问题的框架则由各类业务平台团队提供,这再一次证明了康威定律的正确性。康威定律翻译成中国的土话差不多就是“屁股决定脑袋”,技术型团队不愿意碰业务问题,而业务平台团队的框架在解决技术问题方面也显得没有技术团队专业,最终的结果是:两种框架割裂得比较厉害。
有一条恶龙,每年要求村庄献祭一个处女,每年这个村庄都会有一个少年英雄去与恶龙搏斗,但无人生还。又一个英雄出发时,有人悄悄尾随。龙穴铺满金银财宝,英雄用剑刺死恶龙,然后坐在尸身上,看着闪烁的珠宝,慢慢地长出鳞片、尾巴和触角,最终变成恶龙。
能够帮助开发屏蔽云资源的管理。开发都不喜欢像写汇编一样写 yaml,因此框架需要负责资源的分配、回收,编排等等; 纯异步的,事件驱动的。这是云天生的分布式特性决定的,如果编程语言范式还是同步的模型,这个框架就没法实现了; 没有 vendor lock-in。不绑定实际的云厂商,唯有厂商中立的开发框架才能被广泛使用,框架定义了编程 API,具体的厂商可以提供相关的 driver; 同时具备云资源管理和大规模软件开发必须的编程范式。这里的编程范式可能描述不当,但我找不到更好的词,面向对象设计是最主流的编程范式,Spring 就是围绕这个编程范式展开的。在一个框架中解决两个问题,会给开发极好的体验。
小结
Serverless 这个领域看起来极其美好,一旦深入去做了才发现实际非常复杂。这个复杂体现在涉及的工程技术比较广,也体现在用户的期望差异很大,更体现在大家对未来的判断还有很大的差异。